//
// Created by 19y on 2025/9/25.
//

#include "fatfs_task.h"
#include "FreeRTOS.h"
#include "task.h"
#include <string.h>
#include <stdio.h>

#include "event_groups.h"
#include "freertos_demo.h"
#include "printf_rtos.h"
#include "malloc_ex.h"
#include "semphr.h"
#include "lwip/sockets.h"
/**
 * @brief  FATFS功能测试任务
 * @param  pvParameters: 任务参数(未使用)
 * @retval None
 */
extern EventGroupHandle_t g_init_eventgroup;
static FATFS *fs=NULL;           /* 文件系统对象 */
static FIL *fil=NULL;            /* 文件对象 */

void fatfs_storage_init(void *pvparams)
{
    FRESULT res=-1;//接收操作返回值
    if (fs==NULL)
        fs=(FATFS *)mymalloc(SRAMEX,sizeof(FATFS));
    if (fil==NULL)
        fil=(FIL *)mymalloc(SRAMEX,sizeof(FIL));
    while (res!=FR_OK)
    {
        res=f_mount(fs,"1:",1);
        vTaskDelay(100);
    }
    if (g_init_eventgroup!=NULL)
    {
        xEventGroupSetBits(g_init_eventgroup,BIT_FATFS_READY);
    }
    vTaskDelete(NULL);
}

void fatfs_write_str_to_storage(const TCHAR *path, const char *str)
{
    assert(path);
    assert(str);
    assert(g_init_eventgroup);
    xEventGroupWaitBits(g_init_eventgroup,BIT_FATFS_READY,pdFALSE\
        ,pdTRUE,portMAX_DELAY);
    // static FATFS *fs=NULL;           /* 文件系统对象 */
    // static FIL *fil=NULL;            /* 文件对象 */
    static SemaphoreHandle_t write_mutex=NULL;//写入互斥锁
    // static bool init_flag=false;
    FRESULT res;//接收操作返回值
    uint32_t bytes_written;
    // if (fs==NULL)
    //     fs=mymalloc(SRAMEX,sizeof(FATFS));
    // if (fil==NULL)
    //     fil=mymalloc(SRAMEX,sizeof(FIL));
    if (write_mutex==NULL)
        write_mutex=xSemaphoreCreateMutex();
    if (xSemaphoreTake(write_mutex,pdMS_TO_TICKS(2000))!=pdTRUE)
        return;
    // if (!init_flag)
    // {
    //     res=f_mount(fs,path,1);
    //     if (res!=FR_OK)
    //     {
    //         xSemaphoreGive(write_mutex);
    //         return;
    //     }
    //     init_flag=true;
    // }

    res=f_open(fil,path,FA_OPEN_APPEND|FA_WRITE);
    if (res!=FR_OK)
    {
        xSemaphoreGive(write_mutex);
        return;
    }
    res=f_write(fil,str,strlen(str),&bytes_written);
    if (res==FR_OK)
    {
        f_sync(fil);
    }
    res=f_close(fil);
    xSemaphoreGive(write_mutex);
}

void fatfs_test_task(void *pvParameters)
{
    /* 任务参数未使用 */
    (void)pvParameters;

    static FATFS *fs=NULL;           /* 文件系统对象 */
    static FIL *fil=NULL;            /* 文件对象 */

    if (fs==NULL)
        fs=(FATFS *)mymalloc(SRAMEX,sizeof(FATFS));
    if (fil==NULL)
        fil=(FIL *)mymalloc(SRAMEX,sizeof(FIL));
    FRESULT res;        /* FatFs函数执行结果 */
    UINT bytes_written, bytes_read; /* 已写入/读取的字节数 */

    /* 准备要写入的测试数据 */
    const char test_data[] = "Hello from FreeRTOS! This is a test of the FatFs integration.";

    /* 准备一个足够大的缓冲区用于读回数据 */
    char read_buffer[sizeof(test_data) + 1] = {0};

    /* --- 测试任务主循环 --- */
    for (;;)
    {
        printf_rtos("\r\n--- [FATFS Test Task] Starting Test Cycle ---\r\n");

        /* 步骤 1: 挂载文件系统 */
        /* "1:" 是驱动器路径, 1 表示立即挂载 */
        res = f_mount(fs, "1:", 1);
        if (res != FR_OK)
        {
            printf_rtos("[ERROR] f_mount failed! Error code: %d\r\n", res);
            vTaskDelay(pdMS_TO_TICKS(5000)); // 挂载失败，等待5秒后重试
            continue; // 继续下一次循环
        }
        printf_rtos("[OK] Filesystem mounted successfully.\r\n");

        /* 步骤 2: 打开文件用于写入，如果不存在则创建 */
        /* "test_freertos.txt" 是测试文件名 */
        res = f_open(fil, "1:test_freertos.txt", FA_CREATE_ALWAYS | FA_WRITE);
        if (res != FR_OK)
        {
            printf_rtos("[ERROR] f_open (for writing) failed! Error code: %d\r\n", res);
            f_mount(NULL, "1:", 1); // 出错时卸载
            vTaskDelay(pdMS_TO_TICKS(5000));
            continue;
        }
        printf_rtos("[OK] File 'test_freertos.txt' opened for writing.\r\n");

        /* 步骤 3: 写入数据 */
        res = f_write(fil, test_data, strlen(test_data), &bytes_written);
        if (res != FR_OK || bytes_written != strlen(test_data))
        {
            printf_rtos("[ERROR] f_write failed! Error code: %d, Bytes written: %u\r\n", res, bytes_written);
            f_close(fil);
            f_mount(NULL, "1:", 1);
            vTaskDelay(pdMS_TO_TICKS(5000));
            continue;
        }
        printf_rtos("[OK] Wrote %u bytes to file.\r\n", bytes_written);

        /* 步骤 4: 关闭文件 (这将刷新所有缓存并写入磁盘) */
        res = f_close(fil);
        if (res != FR_OK)
        {
            printf_rtos("[ERROR] f_close (after writing) failed! Error code: %d\r\n", res);
            f_mount(NULL, "1:", 1);
            vTaskDelay(pdMS_TO_TICKS(5000));
            continue;
        }
        printf_rtos("[OK] File closed after writing.\r\n");

        /* --- 验证阶段 --- */

        /* 步骤 5: 重新打开文件用于读取 */
        res = f_open(fil, "1:test_freertos.txt", FA_READ);
        if (res != FR_OK)
        {
            printf_rtos("[ERROR] f_open (for reading) failed! Error code: %d\r\n", res);
            f_mount(NULL, "1:", 1);
            vTaskDelay(pdMS_TO_TICKS(5000));
            continue;
        }
        printf_rtos("[OK] File re-opened for reading.\r\n");

        /* 步骤 6: 读取文件内容 */
        res = f_read(fil, read_buffer, sizeof(read_buffer) - 1, &bytes_read);
        if (res != FR_OK)
        {
            printf_rtos("[ERROR] f_read failed! Error code: %d\r\n", res);
            f_close(fil);
            f_mount(NULL, "1:", 1);
            vTaskDelay(pdMS_TO_TICKS(5000));
            continue;
        }
        printf_rtos("[OK] Read %u bytes from file.\r\n", bytes_read);

        /* 步骤 7: 数据校验 */
        if (bytes_read == bytes_written && memcmp(test_data, read_buffer, bytes_written) == 0)
        {
            printf_rtos("[SUCCESS] Data verification passed!\r\n");
        }
        else
        {
            printf_rtos("[FAILURE] Data verification FAILED!\r\n");
            printf_rtos("  - Wrote: \"%s\"\r\n", test_data);
            printf_rtos("  - Read:  \"%s\"\r\n", read_buffer);
        }

        /* 步骤 8: 关闭并删除测试文件，清理现场 */
        f_close(fil);
        res = f_unlink("1:test_freertos.txt");
        if (res != FR_OK)
        {
            printf_rtos("[WARNING] f_unlink failed to delete test file. Error code: %d\r\n", res);
        }
        else
        {
            printf_rtos("[OK] Test file 'test_freertos.txt' deleted.\r\n");
        }

        /* 步骤 9: 卸载文件系统 */
        f_mount(NULL, "1:", 1);
        printf_rtos("--- [FATFS Test Task] Test Cycle Finished ---\r\n");

        /* 等待一段时间后开始下一轮测试 */
        UBaseType_t stack_high_water_mark = uxTaskGetStackHighWaterMark(NULL);
        printf_rtos("fatfs_task high water marks:%d\r\n", stack_high_water_mark);
        vTaskDelay(pdMS_TO_TICKS(10000)); // 每10秒测试一次
    }
}

